<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    function doublePoint(nums, target) {
      // 先对数组进行排序(升序)
      nums.sort((a, b) => a - b)
      // 定义输出数组
      let outArray = []
      // 从首位元素遍历数组，确定第一位数
      for (let i = 0; i < nums.length; i++) {
        // 如果该数不为首位元素，且该数等于上一位数，则证明该数在上一次已被计算，避免重复本次则跳过
        // 由于是升序数组，每次仅需与上一数字比较是否相等即可
        if (i != 0 && nums[i - 1] == nums[i]) continue
        // 从第一位数的下一位数开始遍历，确定第二位书
        for (let j = i + 1; j < nums.length; j++) {
          // 同上判断是否重复
          if (j != i + 1 && nums[j - 1] == nums[j]) continue
          // 第三位从第二位数的下一位数开始遍历
          let n = j + 1
          // 第四位数从最后一位元素开始遍历
          let m = nums.length - 1
          // 当第三位数的位置超过了第四位数，证明已遍历完成所有元素
          while (n < m) {
            // 同上判断是否重复，重复则将位置向后移动一位，跳过本次计算
            if (n != j + 1 && nums[n - 1] == nums[n]) {
              n++
              continue
            }
            // 同上判断是否重复，重复则将位置向前移动一位，跳过本次计算
            if (m != nums.length - 1 && nums[m + 1] == nums[m]) {
              m--
              continue
            }
            // 计算差值
            let DValue = target - (nums[i] + nums[j] + nums[n] + nums[m])
            // 如果等于0，则证明四个元素和为target，则记录四个元素
            if (DValue == 0) {
              outArray.push([nums[i], nums[j], nums[n], nums[m]])
              n++
              m--
            }
            // 如果差值大于零，则证明四数之和小于target，此时应当增大四数之和来接近target，
            // 由于数组是升序的，因此仅需第三位数向后移动即可增大四数之和
            else if (DValue > 0) n++
            // 反之则第四数向前移动即可减少四数之和
            else m--
          }
        }
      }
      return outArray
    }
  </script>
</body>

</html>